package com.devMode.CompositeMode;

import java.util.ArrayList;
import java.util.List;

/**
 * 组合模式
 * 将对象组合成树形结构来表示 整体/部分 的层次关系，允许用户以相同的方式处理组合或者单独对象
 *
 *
 */
public class CompositeMode {
    public static void main(String[] args) {
        Composite root = new Composite("root");
        Component node1 = new Leaf("1");
        Component node2 = new Composite("2");
        Component node3 = new Leaf("3");
        root.add(node1);
        root.add(node2);
        root.add(node3);
        Component node21 = new Leaf("21");
        Component node22 = new Composite("22");
        node2.add(node21);
        node2.add(node22);
        Component node221 = new Leaf("221");
        node22.add(node221);
        root.print();
    }
}

/**
 * 定义抽象模板
 */
abstract class Component{
    protected String name;

    public Component(String name){
        this.name = name;
    }

    public void print(){
        print(0);
    }

    abstract void print(int level);

    abstract public void add(Component component);

    abstract public void remove(Component component);
}

/**
 * 普通节点
 */
class Composite extends Component{

    private List<Component> childs;

    public Composite(String name){
        super(name);
        childs = new ArrayList<>();
    }

    /**
     * 递归打印
     */
    @Override
    void print(int level) {
        for(int i=0; i<level; i++){
            System.out.print("--");
        }
        System.out.println("Composite: "+ name);
        for(Component component : childs){
            component.print(level + 1);
        }
    }

    @Override
    public void add(Component component) {
        childs.add(component);
    }

    @Override
    public void remove(Component component) {
        childs.remove(component);
    }
}

/**
 * 叶子节点
 */
class Leaf extends Component{

    public Leaf(String name){
        super(name);
    }

    @Override
    void print(int level) {
        for(int i=0; i<level; i++){
            System.out.print("--");
        }
        System.out.println("leaf: " + name);
    }

    @Override
    public void add(Component component) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void remove(Component component) {
        throw new UnsupportedOperationException();
    }
}
